import { PlayerParams } from '../Basic/Config/DataConfig';
import { Singleton } from '../Basic/Manager/BaseManager';
import { GameData } from '../Basic/Manager/DataManager';
import { MultiPlatform, Platform } from '../Basic/Model/Platform/MultiPlatform';
import { CallBackHandler } from '../Basic/Model/PoolObj/CallBackHandler';
import { GEEvent } from '../Game/Config/GameEnum';

export class GravityModel extends Singleton {
  className: string = 'GravityModel';
  static ACCESS_TOKEN_TT = 'zBkP26RJZoo93eHfsap4zgVT17bMWtci';
  static ACCESS_TOKEN_WX = 'Kes2EhaWeugHNpCFGiql6j7sk4bTXRDo';
  ge: GravityAnalyticsAPI;
  /** 运行SDK */
  setupAndStart(callback?: CallBackHandler) {
    const accessToken = MultiPlatform.Ins().platform === Platform.wx ? GravityModel.ACCESS_TOKEN_WX : GravityModel.ACCESS_TOKEN_TT;
    const config = {
      accessToken: accessToken, // 项目通行证，在：网站后台-->设置-->应用列表中找到Access Token列 复制（首次使用可能需要先新增应用）
      clientId: GameData.playerParams.get(PlayerParams.openId), // 项目ID，在：网站后台-->设置-->应用列表中找到Client ID列 复制户唯一标识，如产品为小游戏，则必须填用户openid（注意，不是小游戏的APPID！！！）
      autoTrack: {
        appLaunch: true, // 自动采集 $MPLaunch
        appShow: true, // 自动采集 $MPShow
        appHide: true, // 自动采集 $MPHide
        pageShow: true, // 自动采集 $MPViewScreen
        pageShare: true, // 自动采集 $MPShare
        sendTimeout: 3000, // 网络请求超时时间，单位毫秒，默认值 3000 ms
        maxRetries: 3, // 网络请求失败时的重试次数，1 表示不重试。默认值是 3
        enablePersistence: true, // 是否使用本地缓存，主实例默认为 true，子实例默认为 false
        asyncPersistence: false, // 是否使用异步存储，默认为 false
        debug: 'true',
      },
      name: 'ge', // 全局变量名称
      // 是否开启测试模式，开启测试模式后，可以在 网站后台--设置--元数据--事件流中查看实时数据上报结果。（测试时使用，上线之后一定要关掉，改成none或者删除）
      debugMode: 'none',
      // debugMode: 'debug',
    };
    this.ge = new GravityAnalyticsAPI(config);
    this.ge.setupAndStart();
    this.ge
      .initialize({
        name: GameData.playerParams.get(PlayerParams.nickname),
        version: 100,
        openid: GameData.playerParams.get(PlayerParams.openId),
        enable_sync_attribution: false,
      })
      .then((res) => {
        console.log('initialize success ' + JSON.stringify(res).toString());
        callback?.execute();
      })
      .catch((err) => {
        console.log('initialize failed, error is ' + JSON.stringify(err).toString());
      });
  }

  /** 初始化公共属性 */
  initSuperProperties() {
    // this.setSuperProperties(GEEvent.GAME_START);
    // this.setSuperProperties(GEEvent.LOAD);
    // this.setSuperProperties(GEEvent.LOGIN);
    // this.setSuperProperties(GEEvent.AD_SHOW);
    // this.setSuperProperties(GEEvent.AD_SHOW_END);
    // this.setSuperProperties(GEEvent.ONLINE_TIME);
    // this.setSuperProperties(GEEvent.GUIDE);
    // this.setSuperProperties(GEEvent.STAGE_CHALLENGE);
    // this.setSuperProperties(GEEvent.MONEY_CHANGE);
    // this.setSuperProperties(GEEvent.DAILY_SHOP_BUY);
  }

  /** 设置公共事件 */
  setSuperProperties(data) {
    // eg: ge.setSuperProperties({ step: "第三关" });
    this.ge?.setSuperProperties(data);
  }

  // 开始计时，记录的事件为 @eventType
  timeEvent(eventType: string) {
    // eg: this.ge?.timeEvent('Enter_Shop');
    this.ge?.timeEvent(eventType);
  }

  /** 上报 */
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  track(eventName: GEEvent, data: any = null, date: number = null) {
    // eg:
    // this.ge?.track(
    //   "Purchase", //追踪事件的名称
    //   {
    //     Item: "商品A",
    //     ItemNum: 1,
    //     Cost: 100,
    //     onComoplete:(res)=>{
    //      console.log(res);
    //     },
    //   } //需要上传的事件属性
    // );
    this.ge?.track(
      eventName, // 追踪事件的名称
      data == null ? {} : data, // 需要上传的事件属性
      date == null ? Date.now() : date // 事件触发时间
    );
  }

  // 清除属性名为 ${eventName} 的公共属性
  unsetSuperProperty(eventName: string) {
    // eg: ge.unsetSuperProperty("CHANNEL");
    this.ge?.unsetSuperProperty(eventName);
  }

  // 清除公共事件属性
  clearSuperProperties() {
    this.ge?.clearSuperProperties();
  }

  // 获取静态公共事件属性
  getSuperProperties() {
    this.ge?.getSuperProperties();
  }
  /**
   * 上报付费事件
   * @param payAmount     付费金额 单位为分
   * @param payType       货币类型 按照国际标准组织ISO 4217中规范的3位字母，例如CNY人民币、USD美金等
   * @param orderId       订单号
   * @param payReason     付费原因 例如：购买钻石、办理月卡
   * @param payMethod     付费方式 例如：支付宝、微信、银联等
   */
  payEvent(payAmount: number, payType: string, orderId: string, payReason: string, payMethod: string) {
    // eg: this.ge?.payEvent(300, 'CNY', 'your_order_id', '月卡', '支付宝');
    this.ge?.payEvent(payAmount, payType, orderId, payReason, payMethod);
  }

  /**
   * 上报广告展示事件 参数如下
   * @param adType                广告类型 （取值为：reward、banner、native、interstitial、video_feed、video_begin，分别对应激励视频广告、Banner广告、原生模板广告、插屏广告、视频广告、视频贴片广告）
   * @param adUnitId              广告位ID（一般以adunit开头，注意不要填错，会导致广告收入统计不准！）
   * @param otherProperties       其他需要携带的自定义参数
   */
  adShowEvent(adType: string, adUnitId: string, otherProperties = null) {
    // eg: this.ge?.adShowEvent('reward', 'your_ad_unit_id', { custom_param: '' });
    this.ge?.adShowEvent(adType, adUnitId, otherProperties == null ? {} : { custom_param: otherProperties });
  }

  // 设置用户属性，会员等级
  userSet(data) {
    // eg: this.ge?.userSet({ vip_level: "钻石会员" });
    this.ge?.userSet(data);
  }

  // 以设置用户名为例，如果用户名已设置，则忽略本次设置，如果不存在，则设置为传入值
  userSetOnce(data) {
    // this.ge?.userSetOnce({ user_name: 'TestUser' });
    this.ge?.userSetOnce(data);
  }

  /** 累加用户属性 */
  userAdd(data) {
    // 以付费为例，用户每次付费时调用此接口，则'total_revenue'字段每次会做累加付费金额的处理
    // eg: this.ge?.userAdd({ total_revenue: 50 });
    this.ge?.userAdd(data);
  }
  /** 重置用户属性 */
  userUnset(key: string) {
    // 清空属性名为userPropertyKey的用户属性值该用户，即设置成NULL
    // eg: this.ge?.userUnset('userPropertyKey');
    this.ge?.userUnset(key);
  }

  /** 清空用户属性 */
  userDel() {
    this.ge?.userDel();
  }

  /** Array 属性 追加 */
  usrAppend(data) {
    // eg: this.ge?.userAppend({ Movies: ["Interstellar", "The Negro Motorist Green Book"] });
    this.ge?.userAppend(data);
  }

  /**
   * 数数
   * CURRENT_USER_TA_ACCOUNT_ID：当前用户的数数账户 ID (#account_id)
   * CURRENT_USER_TA_DISTINCT_ID：当前用户的数数访客 ID (#distinct_id)
   */
  bindTAThirdPlatform(CURRENT_USER_TA_ACCOUNT_ID: string, CURRENT_USER_TA_DISTINCT_ID: string) {
    this.ge?.bindTAThirdPlatform(CURRENT_USER_TA_ACCOUNT_ID, CURRENT_USER_TA_DISTINCT_ID);
  }
}
